package com.bckj.fastboot.core.util;

import java.lang.invoke.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

public class BeanAccessor<T> {
    private final Map<String, Function<T, Object>> accessors = new HashMap<>();

    public BeanAccessor(Class<T> beanClass) throws Exception {
        MethodHandles.Lookup lookup = MethodHandles.lookup();
        
        for (java.lang.reflect.Field field : beanClass.getDeclaredFields()) {
            String fieldName = field.getName();
            String getterName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
            
            try {
                MethodHandle handle = lookup.findVirtual(beanClass, getterName, 
                    MethodType.methodType(field.getType()));
                
                // 编译为函数式接口
                CallSite callSite = LambdaMetafactory.metafactory(
                    lookup,
                    "apply",
                    MethodType.methodType(Function.class),
                    MethodType.methodType(Object.class, Object.class),
                    handle,
                    handle.type());
                
                @SuppressWarnings("unchecked")
                Function<T, Object> accessor = (Function<T, Object>) callSite.getTarget().invoke();
                accessors.put(fieldName, accessor);
            } catch (Throwable e) {
                // 处理无getter的情况
            }
        }
    }

    public Optional<Object> getValue(T bean, String fieldName) {
        return Optional.ofNullable(accessors.get(fieldName)).map(p -> p.apply(bean));
    }

    public Map<String, Object> getAllValues(T bean) {
        return accessors.entrySet().stream()
            .collect(Collectors.toMap(
                Map.Entry::getKey,
                e -> e.getValue().apply(bean))
            );
    }
}